home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume2 / refer2tex < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  9.8 KB

  1. From: dfk@duke.cs.duke.edu (David Kotz)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i097: sources for refer => BiBTeX conversion
  4. Message-ID: <11581@duke.cs.duke.edu>
  5. Date: 15 Apr 88 15:22:11 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. comp.sources.misc: Volume 2, Issue 97
  9. Submitted-By: "David Kotz" <dfk@duke.cs.duke.edu>
  10. Archive-Name: refer2tex
  11.  
  12. #! /bin/sh
  13. # This is a shell archive, meaning:
  14. # 1. Remove everything above the #! /bin/sh line.
  15. # 2. Save the resulting text in a file.
  16. # 3. Execute the file with /bin/sh (not csh) to create the files:
  17. #    refer2tex
  18. #    bibfix.sed
  19. #    r2bib.c
  20. # This archive created: Fri Apr 15 09:17:47 1988
  21. export PATH; PATH=/bin:$PATH
  22. if test -f 'refer2tex'
  23. then
  24.     echo shar: will not over-write existing file "'refer2tex'"
  25. else
  26. cat << \SHAR_EOF > 'refer2tex'
  27. #!/bin/csh -f
  28. #
  29. # refer2tex: translate a refer bibliography to a bibtex one.
  30. #  Sort of. It may need some manual help but this is an approximation.
  31. #
  32. # David Kotz
  33. #
  34. # usage: refer2tex bibfile
  35. # produces bibfile.bib, in BibTex format
  36. #
  37.  
  38. onintr cleanup
  39. set tmp=/tmp/$1.fix$$
  40.  
  41. if ($#argv < 1) then
  42.     echo usage: refer2tex bibfile
  43.     exit
  44. endif
  45.  
  46. sed -f /usr/local/new/bib/bibfix.sed $1 > $tmp
  47. sortbib -sA+D $tmp | r2bib > $1.bib
  48.  
  49. cleanup:
  50. rm -f $tmp
  51. SHAR_EOF
  52. chmod +x 'refer2tex'
  53. fi # end of overwriting check
  54. if test -f 'bibfix.sed'
  55. then
  56.     echo shar: will not over-write existing file "'bibfix.sed'"
  57. else
  58. cat << \SHAR_EOF > 'bibfix.sed'
  59. # Fix any cutoff lines
  60. s/\(..*\)%A/\1 (CUT OFF BY LOOKBIB)\
  61. \
  62. %A/
  63.  
  64. # Change some [nt]roff garbage into latex equivalent
  65. s/\\(co/\\copyright/g
  66. s/\\fI/{\\em /g
  67. s/\\fB/{\\bf /g
  68. s/\\fR/}/g
  69. s/\\(em/---/g
  70. s/\\\*-/---/g
  71.  
  72. # these must be protected against happening twice
  73. # this changes & to \&
  74. s/\([^\\]\)&/\1\\\&/g
  75. # this changes $ to \$
  76. s/\([^\\]\)\$/\1\\\$/g
  77. # this changes - to -- in pages lines
  78. /pages/s/\([^-]\)-\([^-]\)/\1--\2/g
  79. SHAR_EOF
  80. fi # end of overwriting check
  81. if test -f 'r2bib.c'
  82. then
  83.     echo shar: will not over-write existing file "'r2bib.c'"
  84. else
  85. cat << \SHAR_EOF > 'r2bib.c'
  86. /* r2bib - convert refer input files to bibtex .bib files
  87.    Author - Rusty Wright, Center for Music Experiment, UCSD
  88.    Modified by - Rod Oldehoeft, LLNL & Colorado State University:
  89. From: Rod Oldehoeft <rro@lll-crg.ARPA>
  90.       1.  Accept a lower-case refer letter code as well as upper case
  91.       2.  Map "%X" refer entry to "note=" bibtex entry
  92.       3.  A "%B" entry results in "@inbook" result
  93.       4.  Use {} instead of "" to bracket output fields
  94.      5.  Map "%M" to "month=" bibtex entry
  95.      6.  Map "%Y" to "year=" bibtex entry
  96.       7.  Try to make bibtex entry key from author initials and year
  97.    Modified by David Kotz, Duke University Computer Science (dfk@cs.duke.edu):
  98.    1. Fixed a bug (indirect through NULL) found when run on Suns.
  99.    2. Make the keyword generator smarter about dates and repeated entries.
  100.       To use this effectively do a 'sortbib -sA+D' on the file before sending
  101.      it through here.
  102.    3. map %K to keywords and %X to abstract instead of note. %O maps to note.
  103. */
  104. # include <ctype.h>
  105. # include <stdio.h>
  106.  
  107. struct rb {
  108.     char    rb_kl;        /* refer key letter        */
  109.     char *    rb_kw;        /* bibtex string        */
  110.     char    rb_emit;    /* don't print data if 0    */
  111.     char *    rb_data;    /* refer data            */
  112. };
  113.  
  114. struct rb rb[] = {
  115.     { 'A',    "author",        1,    NULL    },
  116.     { 'B',    "booktitle",    1,    NULL    },
  117.     { 'C',    "address",    1,    NULL    },
  118.     { 'D',    "year",        1,    NULL    },
  119.     { 'E',    "editor",        1,    NULL    },
  120. /*    { 'H',    "commentary1",    1,    NULL    },*/
  121.     { 'I',    "publisher",    1,    NULL    },
  122.     { 'J',    "journal",    1,    NULL    },
  123.     { 'K',    "keywords",    1,    NULL    },
  124.     { 'L',    "label",        0,    NULL    },    /* use as bibtex key */
  125.      { 'M',    "month",        1,    NULL },
  126.     { 'N',    "number",        1,    NULL    },
  127.     { 'O',    "note",        1,    NULL    },
  128.     { 'P',    "pages",        1,    NULL    },
  129.     { 'Q',    "institution",    1,    NULL    },
  130.     { 'R',    "report",        0,    NULL    },
  131.     { 'S',    "series",        1,    NULL    },
  132.     { 'T',    "title",        1,    NULL    },
  133.     { 'V',    "volume",        1,    NULL    },
  134.     { 'X',    "abstract",    1,    NULL    },
  135.     { 'Y',    "year",        1,    NULL },
  136.     { 0,    0,        0,    0    }
  137. };
  138.  
  139. struct bmap {
  140.     char    bm_kl;
  141.     char    *bm_entry;
  142. };
  143.  
  144. /*
  145.  * entries are in order of precedence.
  146.  * any entry with a 'J' field must be
  147.  * an article, but anthing with an 'I'
  148.  * field doesn't have to be a book (if
  149.  * an entry has both 'J' and 'I' it is
  150.  * considered to be an article).
  151.  */
  152. struct bmap    bmap[] = {
  153.     { 'J',    "article"    },
  154.     { 'R',    "techreport"    },
  155.     { 'I',    "book"    },
  156.     { 'B',    "inbook"    },
  157.     { 0,    0        }
  158. };
  159.  
  160. main(argc, argv)
  161.     char        **argv;
  162. {
  163.     register FILE    *fid;
  164.     register int    i;
  165.     int        err;
  166.  
  167.     err = 0;
  168.  
  169.     if (argc > 1) {
  170.         for (i = 1; i < argc; i++) {
  171.             if ((fid = fopen(argv[i], "r")) == NULL) {
  172.                 fprintf(stderr, "fopen: ");
  173.                 perror(argv[i]);
  174.                 continue;
  175.             }
  176.             err += r2bib(argv[i], fid);
  177.         }
  178.     }
  179.     else
  180.         err += r2bib("stdin", stdin);
  181.  
  182.     if (err)
  183.         exit(1);
  184.  
  185.     exit(0);
  186. }
  187.  
  188. r2bib(file, fid)
  189.     char        *file;
  190.     FILE        *fid;
  191. {
  192.     extern char    *sanz();
  193.     register char    *cp;
  194.     struct rb    *lrb;        /* last rb stored into */
  195.     int        line;
  196.     char        buf[BUFSIZ];
  197.     int        err;
  198.  
  199.     lrb = NULL;
  200.     err = 0;
  201.     line = 0;
  202.  
  203.     while (fgets(buf, sizeof(buf), fid) != NULL) {
  204.         line++;
  205.  
  206.         if ((cp = sanz(buf)) == NULL) {
  207.             if (lrb != NULL) {
  208.                 dumprb();
  209.                 lrb = NULL;
  210.             }
  211.             continue;
  212.         }
  213.  
  214.         /*
  215.          * if the first letter is a % then it's the
  216.          * a new record, otherwise it's a continuation
  217.          * of the previous one.
  218.          */
  219.         if (cp[0] == '%') {
  220.             for (lrb = &rb[0]; lrb->rb_kl != 0; lrb++) {
  221.                 if(lrb->rb_kl == (islower(cp[1]) ? toupper(cp[1]) : cp[1])){
  222.                     stuffrb(lrb, &cp[2]);
  223.                     break;
  224.                 }
  225.             }
  226.             if (lrb->rb_kl == 0) {
  227.                 fprintf(stderr, "r2b: %s: line %d: unknown key letter %c, ignoring\n", file, line, cp[1]);
  228.                 err = 1;
  229.             }
  230.         }
  231.         else {
  232.             if (lrb == NULL) {
  233.                 fprintf(stderr, "r2b: %s: line %d: bad format, ignoring\n", file, line);
  234.                 err = 1;
  235.                 continue;
  236.             }
  237.  
  238.             stuffrb(lrb, &cp[0]);
  239.         }
  240.     }
  241.  
  242.     if (lrb != NULL)
  243.         dumprb();
  244.  
  245.     return(err);
  246. }
  247.  
  248. #define KEYSIZ 100            /* hopefully long enough */
  249.  
  250. dumprb() {
  251.     register struct rb    *trb;
  252.     register struct bmap    *bm;
  253.     static int        key;
  254.     char            *bibkey;
  255.     char            *cp;
  256.     int            first;
  257.     static char lastkey[KEYSIZ];    /* the previous key we output */
  258.     char thiskey[KEYSIZ];    /* key we are now building */
  259.     static int repeat = 0;
  260.  
  261.     /*
  262.      * first, figure out what type of entry this
  263.      * is.
  264.      */
  265.     for (bm = &bmap[0]; bm->bm_kl != 0; bm++) {
  266.         for (trb = &rb[0]; trb->rb_kl != 0; trb++) {
  267.             if ((trb->rb_kl == bm->bm_kl) && (trb->rb_data != NULL)) {
  268.                 printf("@%s{", bm->bm_entry);
  269.                 goto out;
  270.             }
  271.         }
  272.     }
  273. out:
  274.     if (bm->bm_kl == 0)
  275.         printf("@misc{");
  276.  
  277.     /*
  278.      * in order of precedence; how to determine the
  279.      * bibtex key:
  280.      *    1. use capital letters from %A, followed if possible
  281.       *      by the two chars after "19" in %D or %Y field.
  282.      *    2. otherwise just use the string "keyN" where N
  283.      *       is the count of this bibliographic entry in
  284.      *       the refer file.
  285.      */
  286.  
  287.     key++;
  288.     bibkey = thiskey;
  289.  
  290.     for (trb = &rb[0]; trb->rb_kl != 0; trb++) {
  291.         if( trb->rb_kl == 'A'){
  292.             if( trb->rb_data == NULL ) {
  293.                 sprintf(thiskey, "key%d,\n",key); 
  294.                 printf("key%d",key);
  295.                 break;
  296.             }else{
  297.                 for( cp = trb->rb_data; *cp != NULL; cp++ ) {
  298.                     if( isupper(*cp)) {
  299.                         printf("%c", *cp);
  300.                         *bibkey++ = *cp;
  301.                     }
  302.                 };
  303.                 *bibkey = '\0';
  304.             };
  305.         }else{ if((trb->rb_kl == 'D') || (trb->rb_kl == 'Y')) {
  306.                 for( cp = trb->rb_data; cp != NULL && *cp != NULL; cp++ ) {
  307.                     if(isdigit(cp[0]) && isdigit(cp[1]) &&
  308.                        isdigit(cp[2]) && isdigit(cp[3])) {
  309.                          *bibkey++ = cp[2];
  310.                          *bibkey++ = cp[3];
  311.                         printf("%c%c", cp[2], cp[3]);
  312.                         break;
  313.                     };
  314.                 };
  315.                 *bibkey = '\0';
  316.                 break;
  317.               };
  318.         };
  319.     };
  320.  
  321.     if (strcmp(thiskey, lastkey) == 0) {
  322.         /* key was the same as previous; add a letter */
  323.         printf("%c", 'a' + repeat++);
  324.     } else {
  325.         /* key differed from previous, but remember it */
  326.         strcpy(lastkey, thiskey);
  327.         repeat = 0;
  328.     }
  329.  
  330.     printf(",\n");
  331.  
  332.     first = 1;
  333.  
  334.     for (trb = &rb[0]; trb->rb_kl != 0; trb++) {
  335.         if (trb->rb_data == NULL)
  336.             continue;
  337.  
  338.         if (trb->rb_emit != 0) {
  339.             /*
  340.              * clank,
  341.              * this is so that things will line up.
  342.              */
  343.             if (strlen(trb->rb_kw) < 6)
  344.                 cp = "\t\t";
  345.             else
  346.                 cp = "\t";
  347.  
  348.             if (! first)
  349.                 printf(",\n");
  350.  
  351.             printf("\t%s =%s{%s}", trb->rb_kw, cp, trb->rb_data);
  352.             first = 0;
  353.         }
  354.  
  355.         (void) free(trb->rb_data);
  356.         trb->rb_data = NULL;
  357.     }
  358.  
  359.     printf("\n}\n\n");
  360. }
  361.  
  362. stuffrb(lrb, cp)
  363.     struct rb    *lrb;
  364.     char        *cp;
  365. {
  366.     extern char    *andfix();
  367.     extern char    *malloc();
  368.     extern char    *realloc();
  369.  
  370.     /* empty data field */
  371.     if ((cp = sanz(cp)) == NULL)
  372.         return;
  373.  
  374.     if (lrb->rb_kl == 'A')
  375.         cp = andfix(cp);
  376.  
  377.     if (lrb->rb_data == NULL) {
  378.         if ((lrb->rb_data = malloc(strlen(cp) + 1)) == NULL) {
  379.             perror("malloc");
  380.             exit(1);
  381.         }
  382.  
  383.         strcpy(lrb->rb_data, cp);
  384.     }
  385.     else {
  386.         char    *conj;
  387.  
  388.         if (lrb->rb_kl == 'A')
  389.             conj = " and ";
  390.         else
  391.             conj = " ";
  392.  
  393.         if ((lrb->rb_data = realloc(lrb->rb_data, strlen(lrb->rb_data) + strlen(cp) + strlen(conj) + 1)) == NULL) {
  394.             perror("realloc");
  395.             exit(1);
  396.         }
  397.  
  398.         strcat(lrb->rb_data, conj);
  399.         strcat(lrb->rb_data, cp);
  400.     }
  401. }
  402.  
  403. /*
  404.  */
  405. char *
  406. andfix(string)
  407.     register char    *string;
  408. {
  409.     register char    *tmp;
  410.     register char    *cp;
  411.  
  412.     tmp = string;
  413.  
  414.     for (cp = string; *cp != NULL; cp++) {
  415.         if (strncmp(cp, " and ", 5) == 0) {
  416.             /*
  417.              * +2 for the curly braces around "{and}",
  418.              * +1 for the null at the end.
  419.              */
  420.             if ((tmp = malloc(strlen(string) + 2 + 1)) == NULL) {
  421.                 perror("malloc");
  422.                 exit(1);
  423.             }
  424.  
  425.             strncpy(tmp, string, cp - string);
  426.             tmp[cp - string] = NULL; /* strncpy doesn't */
  427.             strcat(tmp, " {and} ");
  428.             strcat(tmp, cp + 5);
  429.         }
  430.     }
  431.  
  432.     return(tmp);
  433. }
  434.  
  435. char *
  436. sanz(bp)
  437.     char        *bp;
  438. {
  439.     register char    *cp;
  440.  
  441.     cp = &bp[strlen(bp) - 1];
  442.  
  443.     /*
  444.      * back up over any spaces chars
  445.      */
  446.     while (isspace(*cp) && (cp >= bp))
  447.         cp--;
  448.  
  449.     if (cp < bp)
  450.         return(NULL);    /* empty line */
  451.  
  452.     *++cp = NULL;
  453.  
  454.     while (isspace(*bp) && (bp < cp))
  455.         bp++;
  456.  
  457.     if (cp == bp)
  458.         return(NULL);    /* empty line */
  459.  
  460.     return(bp);
  461. }
  462. SHAR_EOF
  463. fi # end of overwriting check
  464. #    End of shell archive
  465. exit 0
  466. -- 
  467. Department of Computer Science, Duke University, Durham, NC 27706
  468. ARPA:    dfk@cs.duke.edu
  469. CSNET:    dfk@duke        
  470. UUCP:    {ihnp4!decvax}!duke!dfk
  471.